/**
 * @author Xiao Xin
 * @version 1.0.0
 * @date 20210311
 * @copyright MIN-Group:国家重大科技基础设施-未来网络北大实验室：深圳市信息论与未来网络重点实验室
 */
var SelfEncodingBase = require('../encoding/SelfEncodingBase').SelfEncodingBase
var Encoder = require('../encoding/Encoder').Encoder
var Block = require('../encoding/Block').Block
var TLV = require('../encoding/TLV')
var {TlvComponentBase} = require('./TlvComponentBase')
var aggregation = require('../common/aggregation')//实现了多继承
var MutableDangerousField =require('./MutableDangerousField').MutableDangerousField
var MutableProtectField = require('./MutableProtectField').MutableProtectField

 /**
  * @description 表示一个MIN包格式中的可变保护区
  * @todo 此处其实是多继承了MutableProtectField、MutableDangerousField两个类，改变为其中的两个属性，如果有问题的话，就去实现多继承中方法同名问题
  */
 class MutableField extends aggregation(TlvComponentBase,SelfEncodingBase){
  constructor(){
    super()
    this.mutableProtectField = new MutableProtectField()
    this.mutableDangerousField = new MutableDangerousField()
  }

  /**
   * @description 将可变区线速编码为一个 TLV
   * @param {Encoder} encoder
   * @param {number}
   */
  wireEncode(encoder){
    var totalLength = 0
    // 编码 TLV-VALUE
    try {
      var tmpLen = this.mutableDangerousField.wireEncode(encoder)
      totalLength += tmpLen
      tmpLen = this.mutableProtectField.wireEncode(encoder)
      totalLength += tmpLen
    } catch (error) {
      throw error
    }

    // 如果可变保护区和可变非保护区均为空，则可以去掉可变区
    if(totalLength == 0){
      return 0
    }

    try {
      //编码 TLV-LENGTH
      tmpLen = encoder.prependVarNumber(BigInt(totalLength))
      totalLength += tmpLen

      //编码 TLV-TYPE
      tmpLen = encoder.prependVarNumber(TLV.FieldType.TlvMutableField)
      totalLength += tmpLen
      return totalLength
    } catch (error) {
      throw error
    }
  }

  /**
   * @description 从 TLV Block中解码初一个 MutableField
   * @param {Block} Block
   */
  wireDecode(block){
    try {
      //检查 TYPE 是否正确
      TLV.expectType(block.getType(),TLV.FieldType.TlvMutableField)

      //解析子 TLV
      block.parseSubElements()
    } catch (error) {
      throw error
    }
      for(var element of block.getSubElements()){
        switch (element.getType()){
          case TLV.FieldType.TlvMutableProtectField:
            try {
              this.mutableProtectField.wireDecode(element)
            } catch (error) {
              throw error
            }
            break;
          case TLV.FieldType.TlvMutableDangerousField:
            try {
              this.mutableDangerousField.wireDecode(element)
            } catch (error) {
              throw error
            }
            break;
          default:
            throw new MutableFieldError("Parse MutableField error, find unexpect TLV-TYPE: "+element.getType())
        }
      }

  }
 }

 //错误处理
class MutableFieldError{
  constructor(m){
    this.msg = m || ""
  }

  static error(){
    console.log("MutableFieldError: "+this.msg)
  }
}

module.exports = {
  MutableField: MutableField,
  MutableFieldError: MutableFieldError
}